package cn.edu.scau.cmi.crawler.service;

import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.edu.scau.cmi.ema.controller.base.CmiEmaController;
import cn.edu.scau.cmi.ema.domain.*;
import cn.edu.scau.cmi.ema.service.base.EntityFactoryService;
import cn.edu.scau.cmi.ema.util.CmiSetUtil;
import cn.edu.scau.cmi.ema.util.CmiTimeUtil;
import cn.edu.scau.cmi.front.dao.CmiFoodDAO;

@Service
public class ShenlirongEventImportServiceImpl extends CmiEmaController implements ShenlirongEventImportService{
	
	@Autowired EntityFactoryService entityFactory;
	
	@Autowired CmiFoodDAO cmiFoodDAO;
	@Override
	public boolean importEvent(Event9slr event9slr) {

		
//		（0）食物必须有，否则不能新建事件
		Food food = buildFood(event9slr);
		if(food == null) {
			System.out.println("Event的Food是空，该数据没有意义");
			event9slr.setImported(false);//没有导入
			event9slrService.saveEvent9slr(event9slr);
			return false;
		}
//		这一步可以忽略，因为foodtype最后还是需要人工确定。
		Foodtype foodtype = buildFoodtype(event9slr);
		food.setFoodtype(foodtype);
		food = foodDAO.store(food);
		foodDAO.flush();
		
//		(1)
		Event event = entityFactory.initEvent();
		
//		（2） 设置默认基本属性	
		event.setAuditTime(Calendar.getInstance());
		event.setAuditor(CmiSetUtil.getFirstInstance(userDAO.findUserByName("沈立荣")));
//		（3）设置基本属性和引用属性
		event.setName(event9slr.getName());
		event.setDescription(event9slr.getDescription());
		
		event.setDiscoveryTime(CmiTimeUtil.getYMDCalendar(event9slr.getDiscoverytime() + "-01-01"));

		Address discoveryAddress = buildDiscoveryAddress(event9slr);
		if(discoveryAddress == null) {
			discoveryAddress = addressDAO.findAddressById(-2);
		}
		event.setDiscoveryAddress(discoveryAddress);
//		沈老师的事件的subject是空，使用-2的代替。
		event.setSubject(subjectDAO.findSubjectById(-2));
//		沈老师的事件的report是美国USP数据库；	
		event.setReportor(userDAO.findUserById(8));
		
		Url url = buildUrl(event9slr);
		event.setUrl(url);
		
//		Adultertype adultertype = buildAdultertype(event9slr);
		Set<Adultertype> adultertypes = buildAdultertype(event9slr);
		event.setAdultertypesForEvent(adultertypes);
		
		Foodbatch foodbatch = entityFactory.initFoodbatch();
		foodbatch.setFood(food);
		foodbatch.setDetectmethod(detectmethodDAO.findDetectmethodById(-2));
		foodbatch.setUnit(unitDAO.findUnitById(-2));
//		foodbatch.setFoodbatchfillersForFoodbatch(foodbatchfillers);
		Calendar date = Calendar.getInstance();
		foodbatch.setDate(date);
		foodbatch.setName(event.getSubject().getName() + event.getName() + "的食物批次");
		foodbatch = foodbatchService.saveFoodbatch(foodbatch);
		
//		食物批次保存后，食物批次的添加物质才能指向这个数据
		Set<Foodbatchfiller> foodbatchfillers = buildFoodbatchfiller(event9slr);
		for(Foodbatchfiller foodbatchfiller : foodbatchfillers) {
			foodbatchfiller.setFoodbatch(foodbatch);
			foodbatchfillerService.saveFoodbatchfiller(foodbatchfiller);
		}

		event.setFoodbatch(foodbatch);
		event = eventService.saveEvent(event);
		
		try {
			event9slrService.deleteEvent9slr(event9slr);
		}catch(Exception e) {
			System.out.println(e);
		}
		return true;
	}

private User buildReportor(Event9slr event9zwz) {
	
	return userDAO.findUserById(4);
	
	/*
	 * User user = entityFactory.initUser(); // 来源是用户，可以包含监管机构、媒体报道等这种抽象的用户。
	 * Set<User> users = userDAO.findUserByName(event9zwz.getSource());
	 * if(users.size() > 0) { user = CmiSetUtil.getLastInstance(users); }else {
	 * user.setName(event9zwz.getSource()); user.setUsername(event9zwz.getSource());
	 * user.setPassword("askfjqej;askdfjpij;nvaeriifjwertjmdsgfwqert234"); user =
	 * userService.saveUser(user); } return user;
	 */
	}

	private Set<Foodbatchfiller> buildFoodbatchfiller(Event9slr event9zwz) {
		Set<Foodbatchfiller> foodbatchfillers = new HashSet<Foodbatchfiller>();
		
		String fillersName = event9zwz.getFoodbatchfiller();
		if(fillersName == null) {
			return null;
		}
		
		String[] fillerNameList = fillersName.split("，");
		for(int i = 0; i< fillerNameList.length; i++) {
//			（1）每一个都是一个添加物质，这些添加的物质需要保存到filler表中
//			（2）保证每一个数据
//			filler通过name也应该只有1个值
			Set<Filler> fillers = fillerDAO.findFillerByName(fillerNameList[i]);
//			先设置为空，根据情况指向特定的filler
			Filler filler = null;
			Foodbatchfiller foodbatchfiller = entityFactory.initFoodbatchfiller();
			if(fillers.size()>0) {
				filler = CmiSetUtil.getFirstInstance(fillers);
				
			}else {
				filler = entityFactory.initFiller();
				filler.setName(fillerNameList[i]);
				filler = fillerService.saveFiller(filler);
			}
			foodbatchfiller.setFoodbatch(foodbatchDAO.findFoodbatchById(-2));
			foodbatchfiller.setFiller(filler);
			foodbatchfiller = foodbatchfillerService.saveFoodbatchfiller(foodbatchfiller);
//			暂时还不能保存，需要设置其他属性，但是好像由问题，非调用实体类的compareTo方法，
			foodbatchfillers.add(foodbatchfiller);
		}
		return foodbatchfillers;
	}

	private Set<Adultertype> buildAdultertype(Event9slr event9zwz) {
		Set<Adultertype> adultertype = new HashSet<Adultertype>();
		
		String[] adultertypesString = event9zwz.getAdultertype().split("、");
		for(String adultertypeString : adultertypesString) {
			Set<Adultertype> adultertypes = adultertypeDAO.findAdultertypeByName(adultertypeString);
			if(adultertypes.size()>0) {
				adultertype.addAll(adultertypes);
			}
		}
		
		if(adultertype.size()<1) {
			adultertype.add(adultertypeDAO.findAdultertypeById(-2));
		}
		return adultertype;
	}

	private Eventadulterlink buildEventadulterlink(Event9slr event9zwz) {
		Eventadulterlink eventadulterlink = entityFactory.initEventadulterlink();
		
		String adulterlinkName = event9zwz.getAdulterlink();
		Set<Adulterlink> adulterlinks = adulterlinkDAO.findAdulterlinkByName(adulterlinkName);
		Adulterlink adulterlink = null;
//		掺假环节也不能修改。这些环节是固定的。
		if(adulterlinks.size() >0) {
			adulterlink = CmiSetUtil.getLastInstance(adulterlinks);
		}else {
			adulterlink = adulterlinkDAO.findAdulterlinkById(-2);
		}
		eventadulterlink.setAdulterlink(adulterlink);
		return eventadulterlink;
	}

//	沈老师的url数据在url和description中都有，如果
	private Url buildUrl(Event9slr event9zwz) {
		Url url = null;
		String urlString = event9zwz.getUrl();
		if(urlString == null || urlString.trim().equals("")) {
			url = urlDAO.findUrlById(-2);
		}else {
			Set<Url> urls = urlDAO.findUrlByName(urlString.trim());
			if(urls.size()>0) {
				url = CmiSetUtil.getFirstInstance(urls);
			}else {
				url = entityFactory.initUri();
				url.setName(urlString.trim());
				url.setValue(urlString.trim());
				url = urlService.saveUrl(url);
			}
		}
		return url;
	}

	private Address buildDiscoveryAddress(Event9slr event9zwz) {
//		有省、市、县地址，先找县，再找市，再找省
		if(event9zwz.getDiscoveryaddress() == null || event9zwz.getDiscoveryaddress().trim().equals("")) {
			return addressDAO.findAddressById(-2);
		}
		Set<Address> countyAddresss = addressDAO.findAddressByName(event9zwz.getDiscoveryaddress());
		if(countyAddresss.size()>0) {
			return CmiSetUtil.getLastInstance(countyAddresss);
		}
		return null;
	}
	
	
	private Detect buildDetect(Event9slr crawlerevent) {
		Detect detect = entityFactory.initDetect();
		return detect;
	}

	private Detectdetail buildDetectdetail(Event9zwz enent9zwz) {
		Detectdetail instance = entityFactory.initDetectdetail();//CmiSetUtil.getSoleInstance(detectdetailDAO.findDetectdetailByName(enent9zwz.getDetectdetail()));
		return instance;
	}


//	没有食物批次，对每一个事件创建一个只适用于链接的食物。食物批次添加一个是否真实的食物批次。
	private Foodbatch buildFoodbatch(Event9slr enent9zwz) {
		Foodbatch foodbatch = entityFactory.initFoodbatch();
		return foodbatch;
	}

	private Food buildFood(Event9slr event9xls) {
		
		String foodName = event9xls.getFood();
		if(foodName == null || foodName.trim().equals("")) {
			return null;
		}
//		Food food = entityFactory.initFood();
		Set<Food> foodsByName = new HashSet<Food>();
		
		String producerName = event9xls.getProducer();
		
//		生产商：如果excel中不存在，
		Producer producer = null;
		if(!( producerName == null || producerName.trim().equals(""))) {
//			生产商名称唯一
			Set<Producer> producers = producerDAO.findProducerByName(event9xls.getProducer());
			if(producers.size()>0) {
				producer = CmiSetUtil.getFirstInstance(producers);			
				
				Set<Food> fs = cmiFoodDAO.findFoodsByNameAndProducer(foodName, producer.getName());
				if(fs.size()>0) {
					return CmiSetUtil.getFirstInstance(fs);
				}
				Food food = entityFactory.initFood();
				food.setName(foodName);
				food.setProducer(producer);
				food = foodService.saveFood(food);
				return food;
			}else {
				producer = entityFactory.initProducer();
				producer.setName(producerName);
				producer = producerService.saveProducer(producer);
				
				Food food = entityFactory.initFood();
				food.setName(foodName);
				food.setProducer(producer);
				food = foodService.saveFood(food);
				return food;
			}
		}else {
//			
//			食物名称查找食物，可能有多个，对每一个进行地址匹配，
			foodsByName = foodDAO.findFoodByName(foodName);
			if(foodsByName.size()==0) {
				Food food = entityFactory.initFood();
				food.setName(foodName);
				food = foodService.saveFood(food);
				return food;
			}			
			
			for (Food foodByName : foodsByName) {
				Set<Foodbatch> foodbatchs = foodbatchDAO.findFoodbatchsByFood(foodByName.getId(), -1, -1);
				
				for (Foodbatch foodbatch : foodbatchs) {
					Set<Event> events = eventDAO.findEventsByFoodbatch(foodbatch.getId(), -1, -1);
					
					for (Event event : events) {
//						每个事件地址。事件来源地址为空，保持到数据库中是-2；
//						TODO 待解决，纯净水没有厂商、来源地、发现地导致多个food的记录缺陷原因：
//						因为数据库中没有地址用的id为-2的地址代替，而电子表格中是空字符串
						
						String eventsourceaddressName = event.getSourceAddress().getName();
						String eventdiscoveryaddressName = event.getDiscoveryAddress().getName();
						String event9xlsDiscoveryAddress = event9xls.getDiscoveryaddress().trim();
//						沈老师的数据没有来源地址
//						（2.1）待入库的事件有发现地址
						if(!event9xlsDiscoveryAddress.equals("")) {
							if(eventdiscoveryaddressName.equals(event9xlsDiscoveryAddress)) {
								return foodByName;
							}
//						（2.2）待入库的事件没有发现地址
						}else {
							if(event.getDiscoveryAddress().getId() == -2) {
								return foodByName;
							}
						}
					}					
				}
			}		
		}
	
//		没有还没有返回，表示没有找到食物，新建一个食物
		Food food = entityFactory.initFood();
		food.setName(foodName);
		food = foodService.saveFood(food);

		return food;
	}

// 获取精确的类型，如果没有找到就使用著类型，如果都为空，就返回-2的那个类型
	private Foodtype buildFoodtype(Event9slr enent9zwz) {
		
		Foodtype foodtype = CmiSetUtil.getSoleInstance(foodtypeDAO.findFoodtypeByName(enent9zwz.getFoodtype()));
		if(foodtype == null) {
			foodtype = foodtypeDAO.findFoodtypeById(-2);
		}
		return foodtype;
	}

	private Subject buildSubject(Event9slr enent9zwz) {
		if(enent9zwz.getSubject() == null) {
			return null;
		}
		
		Subject instance = CmiSetUtil.getSoleInstance(subjectDAO.findSubjectByName(enent9zwz.getSubject()));
		if(instance == null) {
			instance = entityFactory.initSubject();
			instance.setName(enent9zwz.getSubject());
		}
		
		return instance;
	}
}